package com.study.aoki.reactive.auth

import com.study.aoki.reactive.repository.UserRepository
import org.springframework.http.HttpStatus
import org.springframework.stereotype.Component
import org.springframework.web.filter.reactive.ServerWebExchangeContextFilter
import org.springframework.web.server.ServerWebExchange
import org.springframework.web.server.WebFilterChain
import reactor.core.publisher.Mono
import reactor.kotlin.core.publisher.switchIfEmpty
import reactor.kotlin.core.publisher.toMono

/**
 * @author jiahan.zhou
 * @date 2021/7/1
 */
@Component
class AuthenticationFilter(val userRepository: UserRepository) : ServerWebExchangeContextFilter() {

    override fun filter(exchange: ServerWebExchange, chain: WebFilterChain): Mono<Void> {
        val db = exchange.response.bufferFactory().wrap("请登录".toByteArray()).toMono()
        val token = exchange.request.headers["x-token"]
        if (null == token || token.isEmpty()) {
            exchange.response.statusCode = HttpStatus.UNAUTHORIZED
            return exchange.response.writeWith(db)
        }
        return userRepository.findByPhone(token[0])
                .switchIfEmpty {
                    Mono.error { throw InvalidTokenException() }
                }
                .doOnSuccess { exchange.attributes["USER"] = it }
                .flatMap { super.filter(exchange, chain) }
    }


}

class InvalidTokenException : Exception("无效的token")